package com.bby.screentool.manager;

import android.util.Log;

import com.bby.screentool.base.Config;
import com.bby.screentool.base.RuntimeEnv;
import com.bby.screentool.event.Action;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class WebSocketManager {

    private static final String TAG = "WebSocketManager";

    // 单例对象
    private static volatile WebSocketManager instance;

    // OkHttp客户端
    private final OkHttpClient client;

    // WebSocket对象
    private WebSocket webSocket;

    // WebSocket监听器
    private WebSocketListener webSocketListener;

    // 监听器列表
    private final List<WebSocketListener> listeners;

    // 私有构造方法
    private WebSocketManager() {
        client = new OkHttpClient();
        listeners = new ArrayList<>();
        initWebSocketListener();
    }

    // 获取单例对象的方法
    public static WebSocketManager getInstance() {
        if (instance == null) {
            synchronized (WebSocketManager.class) {
                if (instance == null) {
                    instance = new WebSocketManager();
                }
            }
        }
        instance.connect();
        return instance;
    }

    // 初始化WebSocket监听器的方法
    private void initWebSocketListener() {
        webSocketListener = new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                Log.d(TAG, "onOpen: " + response);
                // 通知所有监听器连接成功
                for (WebSocketListener listener : listeners) {
                    listener.onOpen(webSocket, response);
                }
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {
                Log.d(TAG, "onMessage: " + text);
                // 通知所有监听器收到文本消息
                for (WebSocketListener listener : listeners) {
                    listener.onMessage(webSocket, text);
                }
            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                Log.d(TAG, "onMessage: " + bytes);
                // 通知所有监听器收到二进制消息
                for (WebSocketListener listener : listeners) {
                    listener.onMessage(webSocket, bytes);
                }
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                Log.d(TAG, "onClosing: " + code + ", " + reason);
                // 通知所有监听器准备关闭连接
                for (WebSocketListener listener : listeners) {
                    listener.onClosing(webSocket, code, reason);
                }
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                Log.d(TAG, "onClosed: " + code + ", " + reason);
                // 通知所有监听器已经关闭连接
                for (WebSocketListener listener : listeners) {
                    listener.onClosed(webSocket, code, reason);
                }
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                Log.e(TAG, "onFailure: " + t.getMessage(), t);
                // 通知所有监听器发生错误
                for (WebSocketListener listener : listeners) {
                    listener.onFailure(webSocket, t, response);
                }
            }
        };
    }

    // 连接信令服务器的方法
    public void connect() {
        if (webSocket == null) {
            // 创建Request对象，指定信令服务器地址
            String SERVER_URL = String.format("ws://%s:%s/websocket/%s",
                    Config.SERVER_IP, Config.SERVER_PORT,
                    RuntimeEnv.getUserId());
            try {
                Request request = new Request.Builder()
                        .url(SERVER_URL)
                        .build();

                // 创建WebSocket对象，并传入Request对象和WebSocketListener对象
                webSocket = client.newWebSocket(request, webSocketListener);
            } catch (Exception e) {
                Log.e(TAG, "websocket 连接失败", e);
            }
        }
    }

    // 断开信令服务器的方法
    public void disconnect() {
        if (webSocket != null) {
            // 关闭WebSocket连接，并释放资源
            webSocket.close(1000, "Bye");
            webSocket = null;
        }
    }

    // 发送文本消息的方法
    public void send(String text) {
        if (webSocket != null) {
            webSocket.send(text);
        }
    }

    public void send(Action action) {
        if (webSocket == null) {
            connect();
        }
        if (webSocket != null) {
            send(new Gson().toJson(action));
        }
    }

    // 发送二进制消息的方法
    public void send(ByteString bytes) {
        if (webSocket != null) {
            webSocket.send(bytes);
        }
    }

    // 注册监听器的方法
    public void addListener(WebSocketListener listener) {
        if (listener != null && !listeners.contains(listener)) {
            listeners.add(listener);
        }
    }

    // 注销监听器的方法
    public void removeListener(WebSocketListener listener) {
        if (listener != null && listeners.contains(listener)) {
            listeners.remove(listener);
        }
    }
}
